
#include <btBulletDynamicsCommon.h>
#include "motor.h"
#include "debugOpenGL.h"

namespace Fisica {
   MotorFisico* MotorFisico::self = 0;

   MotorFisico::MotorFisico() {
      // Build the broadphase
      broadphase = new btDbvtBroadphase();

      // Set up the collision configuration and dispatcher
      collisionConfiguration = new btDefaultCollisionConfiguration();
      dispatcher = new btCollisionDispatcher(collisionConfiguration);

      // The actual physics solver
      solver = new btSequentialImpulseConstraintSolver;

      // The world.
      dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
      dynamicsWorld->setGravity(btVector3(0,0,-10));

      debug = new DebugOpenGL();
      dynamicsWorld->setDebugDrawer(debug);
      dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
   } 

   MotorFisico::~MotorFisico() {
      delete dynamicsWorld;
      delete debug;
      delete solver;
      delete dispatcher;
      delete collisionConfiguration;
      delete broadphase;
   }

   MotorFisico* MotorFisico::getMotor() {
      if(self)
         return self;
      else{
         self = new MotorFisico();
         return self;
      }
   }

   void MotorFisico::liberarRecursos() {
      if(self) {
         delete self;
         self = 0;
      }
   }

   void MotorFisico::setGravedad(float x, float y, float z) {
      dynamicsWorld->setGravity(btVector3(x, y, z));
   }

   void MotorFisico::agregar(btRigidBody* body) {
      dynamicsWorld->addRigidBody(body);
   }

   void MotorFisico::remover(btRigidBody* body) {
      dynamicsWorld->removeRigidBody(body);
   }

   void MotorFisico::play() {
      dynamicsWorld->stepSimulation(1/60.f,10);
   }

   void MotorFisico::drawDebug() {
      dynamicsWorld->debugDrawWorld();
   }

   btDynamicsWorld* MotorFisico::internal() {
      return dynamicsWorld;
   }
}
